﻿using System;
using System.Collections.Generic;
using System.IO;
using Core;
using Core.Domain.Entities;
using Core.Settings;
using DataMain;
using DataXml.CommunityFiles;

namespace DataXml
{
  public class XmlCommunityImporter
  {
    private string _filePath;

    public XmlCommunityImporter()
    {
      ErrorMessages = new List<string>();
    }

    public XmlCommunity ImportedCommunity { get; private set; }

    public List<string> ErrorMessages { get; private set; }

    public bool ImportSuccessful { get; private set; }

    public bool SourceExists { get; set; }

    public XmlCommunityImporter AttachTo(string filePath)
    {
      SourceExists = File.Exists(filePath);
      if (SourceExists)
      {
        _filePath = filePath;
      }
      else
      {
        ErrorMessages.Add("File not found: " + filePath);
        _filePath = string.Empty;
      }
      return this;
    }

    public XmlCommunityImporter ImportData()
    {
      if (SourceExists)
      {
        try
        {
          using (var file = File.OpenText(_filePath))
          {
            ImportedCommunity = XmlHelper.ReadXml<XmlCommunity>(ModifyContent(file));
            ImportSuccessful = true;
          }
        }
        catch (Exception ex)
        {
          ImportedCommunity = null;
          ImportSuccessful = false;
          ErrorMessages.Add("Error loading file. " + ex.AllMessages());
        }
      }

      return this;
    }

    private MemoryStream ModifyContent(TextReader file)
    {
      var content = file.ReadToEnd();

      content = content.Replace("Pre-Youth", "PreYouth");

      var stream = new MemoryStream();
      var writer = new StreamWriter(stream);
      writer.Write(content);
      writer.Flush();

      stream.Position = 0;
      return stream;
    }

    public static XmlCommunity GetXmlCommunity(out bool successful, out List<string> messages, string communityFilePath)
    {
      var xmlCommunityImporter = new XmlCommunityImporter();

      var xmlCommunity = xmlCommunityImporter.AttachTo(communityFilePath).ImportData().ImportedCommunity;
      successful = xmlCommunityImporter.ImportSuccessful;
      messages = xmlCommunityImporter.ErrorMessages;
      return xmlCommunity;
    }

    public static void SaveToDb(XmlCommunity xmlCommunity, bool addToCurrentCommunityAndElection)
    {
      var env = IoC.Container.Resolve<IEnvironment>();
      Community community;

      var session = 0.GetSession();
      using (var trans = session.BeginTransaction())
      {
        Election election;
        if (addToCurrentCommunityAndElection)
        {
          community = env.Community;
          community.Name = xmlCommunity.Name;

          election = env.Election;
          election.InCommunity = community; // ensure it is linked correctly
        }
        else
        {
          community = new Community
                        {
                              Name = xmlCommunity.Name
                        };
          election = new Election
                       {
                             InCommunity = community
                       };
          community.Elections.Add(election);
        }

        xmlCommunity.CopyIntoNewStructure(community, election);

        session.SaveOrUpdate(community);

        trans.Commit();
      }
    }
  }
}